import { Tool, ToolColor } from '../../../Tool';
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
import * as turf from '@turf/turf';

/**
 * @description: 面积测量
 * @author: zhao_sk
 * @date: 2022-04-08 09:32:54
 */
export class AreaTool extends Tool {
	constructor(viewer, options = {}, ...args) {
		super(arguments);
		this.viewer = viewer;
		this.startDraw = false;
		this.polygonData = [];
		this.moveData = [];
		this.popupItem = null;
	}

	start() {
		this.initMeasure();
		this.viewer.on('click', this.addPolygon);
		this.viewer.on('mousemove', this.addMovePolygon);
		this.viewer.on('contextmenu', this.stopAdd);
	}

	initMeasure() {
		this.polygonData = [
			{
				type: 'Feature',
				geometry: {
					type: 'Polygon',
					coordinates: [[]]
				}
			}
		];
		this.viewer.getCanvas().style.cursor = 'crosshair';
		!this.viewer.getSource('polygon') &&
			this.viewer.addSource('polygon', {
				type: 'geojson',
				data: {
					type: 'FeatureCollection',
					features: []
				},
				maxzoom: 12 //当以更高的缩放级别显示地图时，将使用来自最大缩放的瓦片的数据
			});
		!this.viewer.getLayer('polygon') &&
			this.viewer.addLayer({
				id: 'polygon',
				source: 'polygon',
				type: 'fill',
				paint: {
					// 绘制类属性
					'fill-antialias': true, // 填充时是否反锯齿（可选，默认值为 true）
					'fill-opacity': 0.1, // 填充的不透明度（可选，取值范围为 0 ~ 1，默认值为 1）
					'fill-color': '#FFFF00', // 填充的颜色（可选，默认值为 #000000。如果设置了 fill-pattern，则 fill-color 将无效）
					'fill-outline-color': '#06CEAE' // 描边的颜色（可选，默认和 fill-color 一致。如果设置了 fill-pattern，则 fill-outline-color 将无效。为了使用此属性，还需要设置 fill-antialias 为 true）
				}
			});
		!this.viewer.getLayer('polygon_cap') &&
			this.viewer.addLayer({
				id: 'polygon_cap',
				source: 'polygon',
				type: 'circle',
				paint: {
					// 绘制类属性
					'circle-opacity': 1, // 圆点的不透明度（可选，取值范围为 0 ~ 1，默认值为 1）
					'circle-radius': 4, // 圆点的半径（可选，值 >= 0，默认值为 5，单位：像素）
					'circle-color': '#FFFF00' // 圆点的颜色（可选，默认值为 #000000）
				}
			});
	}

	addPolygon = (e) => {
		this.startDraw = true;
		this.polygonData[0].geometry.coordinates[0].push([e.lngLat.lng, e.lngLat.lat]);
		let geojson = {
			type: 'FeatureCollection',
			features: this.polygonData
		};
		this.viewer.getSource('polygon').setData(geojson);
	};

	addMovePolygon = (e) => {
		if (!this.startDraw) return;
		this.moveData = [
			{
				type: 'Feature',
				geometry: {
					type: 'Polygon',
					coordinates: [[]]
				}
			}
		];
		this.moveData[0].geometry.coordinates[0] = [
			...this.polygonData[0].geometry.coordinates[0],
			[e.lngLat.lng, e.lngLat.lat]
		];
		let geojson = {
			type: 'FeatureCollection',
			features: this.moveData
		};
		this.viewer.getSource('polygon').setData(geojson);

		if (this.moveData[0].geometry.coordinates[0].length < 3) {
			return;
		}
		this.popupItem && this.popupItem.remove();
		let area = this.getArea(this.moveData[0].geometry.coordinates[0]);
		this.popupItem = new mapboxgl.Popup({
			offset: {
				top: [0, 22]
			},
			closeButton: false, //如果为 true ，弹窗右上角将出现关闭按钮。
			closeOnClick: false, //如果为 true ，点击地图时弹窗将关闭。
			className: 'my-class'
		})
			.setLngLat(e.lngLat)
			.setHTML(
				`
        <div>
          <div><span>面积：</span><span>${area}</span></div>
        </div>
      `
			)
			.setMaxWidth('300px')
			.addTo(this.viewer);
	};

	getArea(areaList) {
		let polygon = turf.polygon([[...areaList, areaList[0]]]);
		let area = turf.area(polygon);
		if (area < 1000000) {
			return `${area.toFixed(2)}㎡`;
		} else {
			return `${(area / 1000000).toFixed(2)}k㎡`;
		}
	}

	stopAdd = (e) => {
		if (!this.startDraw) return;
		this.clearListener();
	};

	clearListener() {
		this.startDraw = false;
		this.viewer.getCanvas().style.cursor = '';
		this.viewer.off('click', this.addPolygon);
		this.viewer.off('mousemove', this.addMovePolygon);
		this.viewer.off('contextmenu', this.stopAdd);
	}

	//停止绘制事件
	cancel() {
		this.clearListener();
		this.popupItem && this.popupItem.remove();

		this.viewer.getLayer('polygon') && this.viewer.removeLayer('polygon');
		this.viewer.getLayer('polygon_cap') && this.viewer.removeLayer('polygon_cap');

		this.viewer.getSource('polygon') && this.viewer.removeSource('polygon');
	}
}
AreaTool.toolId = 'AreaTool';
